import axios from 'axios'
import qs from 'qs'
import { setToken, getToken, removeToken } from '@/utils/auth'
import store from '@/store'
import {vue} from '../main.js'
import { envConfig } from './env'


// 接口常用常量
const scope = envConfig.scope
let corpCode = envConfig.corpCode
// 运行环境,合肥版本有区分, 需要更改成HF
const runCorpCode = 'CS'

// 环境的切换
const baseUrl = envConfig.baseUrl
const diyUrl = envConfig.diyUrl
const websocketUrl = envConfig.websocketUrl

// 设置请求超时时间
// URL请求前缀
const URL_PREFIX = true
axios.defaults.timeout = 60000
axios.defaults.baseURL = baseUrl

axios.interceptors.request.use(
  config => {
    const token = getToken()
    if (token) {
      config.headers['authorization'] = token
    }
    // 数组转换
    if(config.method === 'get' || config.method === 'delete' || config.method === 'put'){
      config.paramsSerializer = function(params) {
          return qs.stringify(params, {arrayFormat: 'repeat'})
      }
    }
    return config
  },
  error => {
    console.log(error)
    return Promise.reject(error)
  }
)

axios.interceptors.response.use(response => {
    if(response.config.responseType === 'blob') {
      return Promise.resolve(response)
    }
    const authorization = response.headers['Authorization'] || response.headers['authorization']
    if (authorization !== undefined) {
      setToken(authorization)
    }
    const status = response.status
    if (status === 200 || status === 304 || status === 1000) {
      if (response.data.code === 200) {
        return Promise.resolve(response.data)
      } else {
        if(response.data.code === 1103) { // 无数据
          return Promise.resolve(response)
        }else if(response.data.status === 1000) { // 无数据
          return Promise.resolve(response)
        }else if(response.data.code === 1008){
           // 清除缓存
          localStorage.clear()
          sessionStorage.clear()
          store.dispatch('permission/delMenuList')
          store.dispatch('tagsView/delAllViews', null, { root: true })
          vue.$router.push('/login')
        }else {
          if(response.data.desc){
            vue.$message.error(response.data.desc)
          }else{
            vue.$message.error(response.data.msg)
          }
          return Promise.reject(response)
        }
      }
    } else {
      vue.$message.error(response.data.msg)
    }
    return Promise.reject()
    // return Promise.resolve(response.data)
  },
  error => {
    if (error.response) {
      switch (error.response.status) {
        case 400:
          vue.$message.error(error.response.data.desc)
          break
        case 401:
          removeToken()
          vue.$router.push({ path: '/401' })
          break
        case 404:
          vue.$router.push({ path: '/404' })
          break
        default:
          vue.$message.error(error.response.data.msg)
      }
    } else {
      if (error.message.includes('timeout')) {
        vue.$message.error('请求超时！请检查网络是否正常')
      } else {
        vue.$message.error('请求失败，请检查网络是否已连接')
      }
    }
    return Promise.reject(error)
  }
)

// post请求
export function post(prefix, url, params) {
  return new Promise((resolve, reject) => {
    if (params === undefined) {
      params = {}
    }
    params.scope = scope
    params.corpCode = corpCode
    var postUrl = url
    if (URL_PREFIX) {
      postUrl = prefix + url
    }
    axios.post(postUrl, params).then(res => {
      if (process.env.NODE_ENV !== 'production') {
        console.group()
        console.info('接口:', postUrl)
        console.info('参数:', params)
        console.info('结果:', res)
        console.groupEnd()
      }
      resolve(res)
    }).catch(error => {
      reject(error)
    })
  })
}

// get请求
export function get(prefix, url, params) {
  return new Promise((resolve, reject) => {
    var getUrl = url;
    if (URL_PREFIX) {
      getUrl = prefix + url;
    }
    if (params === undefined) {
      params = {}
    }
    params.scope = scope
    params.corpCode = corpCode
    axios.get(getUrl, {
      params: params
    }).then(res => {
      if (process.env.NODE_ENV !== 'production') {
        console.group()
        console.info('接口:', getUrl)
        console.info('参数:', params)
        console.info('结果:', res)
        console.groupEnd()
      }
      resolve(res.data)
    }).catch(error => {
      reject(error)
    })
  })
}


// put请求
export function put(prefix, url, params) {
  return new Promise((resolve, reject) => {
    if (params === undefined) {
      params = {}
    }
    params.scope = scope
    params.corpCode = corpCode
    var postUrl = url
    if (URL_PREFIX) {
      postUrl = prefix + url
    }
    axios.put(postUrl, params).then(res => {
      if (process.env.NODE_ENV !== 'production') {
        console.group()
        console.info('接口:', postUrl)
        console.info('参数:', params)
        console.info('结果:', res)
        console.groupEnd()
      }
      resolve(res)
    }).catch(error => {
      reject(error)
    })
  })
}


// delete请求
export function del(prefix, url, params) {
  return new Promise((resolve, reject) => {
    var getUrl = url;
    if (URL_PREFIX) {
      getUrl = prefix + url;
    }
    if (params === undefined) {
      params = {}
    }
    params.scope = scope
    params.corpCode = corpCode

    axios.delete(getUrl, {
      params: params
    }).then(res => {
      if (process.env.NODE_ENV !== 'production') {
        console.group()
        console.info('接口:', getUrl)
        console.info('参数:', params)
        console.info('结果:', res)
        console.groupEnd()
      }
      resolve(res)
    }).catch(error => {
      reject(error)
    })
  })
}

export function upload(prefix, url, params, progressCb, cancelToken) {
  return new Promise((resolve, reject) => {
    if (params === undefined) {
      params = {}
    }
    // params.scope = scope
    params.corpCode = corpCode
    var postUrl = url
    if (URL_PREFIX) {
      postUrl = prefix + url
    }


    const formData = new FormData();
    let time = Date.now()
    let loaded = 0
    const config = {
      onUploadProgress: progressEvent => {
        let _time = Date.now()
        let dtime = _time - time
        time = _time

        let _loaded = progressEvent.loaded
        let dloaded = _loaded - loaded
        loaded = _loaded

        let speed = ((dloaded / 1024) / (dtime / 1000)).toFixed('1') // 当前速度

        let oload = (progressEvent.total - loaded) / 1024 // 剩余数据 KB
        let overTime = Math.floor(oload / Math.floor(speed)) // 剩余时间 s

        // console.log(progressEvent)
        console.log(oload, '----oload')
        console.log(Math.floor(speed), '----speed')
        console.log(overTime, '----overTime')

        progressCb && progressCb(~~(loaded / progressEvent.total * 100), `${speed}KB/S`, overTime)
      },
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      timeout: 1000 * 60 * 15
    }

    if (cancelToken) config.cancelToken = cancelToken

    for(const prop in params) {
      formData.append(prop, params[prop])
    }

    axios.post(postUrl, formData, config).then(res => {
      if (process.env.NODE_ENV !== 'production') {
        console.group()
        console.info('接口:', postUrl)
        console.info('参数:', params)
        console.info('结果:', res)
        console.groupEnd()
      }
      resolve(res)
    }).catch(error => {
      if (axios.isCancel(error)) {
        console.log('Request canceled', error.message)
      } else {
        reject(error)
      }
    })
  })
}

export const requestOpts = {
  scope,
  corpCode,
  runCorpCode,
  baseUrl,
  diyUrl,
  websocketUrl
}

// 返回一个数组 首位为取消的token标识 需传入axios config
// 第二位可调用source.cancel()来取消请求，可传入取消原因
export function useCancelToken() {
  const source = axios.CancelToken.source()
  return [source.token, source]
}
